package ru.amse.stroganova.ui.command;

import java.awt.Point;
import java.util.Map;

import ru.amse.stroganova.presentation.EdgePresentation;
import ru.amse.stroganova.presentation.GraphPresentation;
import ru.amse.stroganova.presentation.VertexPresentation;
import ru.amse.stroganova.ui.PresentationController;
import ru.amse.stroganova.ui.layout.Layout;
import ru.amse.stroganova.ui.visual.GraphElementSelection;

/**
 * Presents a factory for making graph presentation commands.
 * 
 * @author Dasha Stroganova
 * 
 */
public class CommandFactory {

	private final GraphPresentation graphPresentation;
	
	private final GraphElementSelection graphSelection;

	/**
	 * Creates new command factory on given presentation.
	 * 
	 * @param graphPresentation
	 * @param graphSelection 
	 */
	public CommandFactory(GraphPresentation graphPresentation, GraphElementSelection graphSelection) {
		this.graphSelection = graphSelection;
		this.graphPresentation = graphPresentation;
	}

	/**
	 * Returns new add vertex command.
	 * 
	 * @param point
	 *            point
	 * @return new add vertex command
	 */
	public Command getNewAddVertexCommand(Point point) {
		return new AddVertexCommand(point, graphPresentation, graphSelection);
	}

	
	/**
	 * Returns new add edge command.
	 * 
	 * @param sourcePr
	 *            source presentation
	 * @param destinPr
	 *            destination presentation
	 * @return new add edge command
	 */
	public Command getNewAddEdgeCommand(VertexPresentation sourcePr, VertexPresentation destinPr) {
		return new AddEdgeCommand(sourcePr, destinPr, graphPresentation, graphSelection);
	}
	
	/**
	 * Returns new edge end editing command.
	 * @param edge edge whose end is changing
	 * @param sourcePr
	 *            source presentation
	 * @param destinPr
	 *            destination presentation
	 * @return new add edge command
	 */
	public Command getNewEdgeEndEditCommand(EdgePresentation edge, VertexPresentation sourcePr, VertexPresentation destinPr) {
		return new EdgeEndEditCommand(edge, sourcePr, destinPr, graphPresentation, graphSelection);
	}

	/**
	 * Returns new delete command.
	 * 
	 * @return new delete command
	 */
	public Command getNewDeleteCommand() {
		return new DeleteCommand(graphPresentation, graphSelection);
	}

	/**
	 * Returns new drag command.
	 * 
	 * @param start
	 *            start point
	 * @param end
	 *            end point
	 * @return new drag command
	 */
	public Command getNewDragCommand(Point start, Point end) {
		return new DragCommand(start, end, graphPresentation, graphSelection);
	}
	
	/**
	 * Returns new drag command.
	 * 
	 * @param beforeDragPositions
	 * @return new drag command
	 */
	public Command getNewDragCommand(Map<VertexPresentation, Point> beforeDragPositions) {
		return new DragCommand(beforeDragPositions, graphPresentation, graphSelection);
	}

	/**
	 * Returns new layout command.
	 * 
	 * @param layout layout
	 * @return new layout command
	 */
	public Command getNewLayoutCommand(Layout layout) {
		return new LayoutCommand(layout, graphPresentation);
	}
	
	/**
	 * Returns new WeightChangeCommand.
	 * 
	 * @param oldWeight
	 *            old weight
	 * @param newWeight
	 *            new weight
	 * @param edge edge changing
	 * @return new weight change command
	 */
	public Command getWeightChangeCommand(int oldWeight, int newWeight,  EdgePresentation edge) {
		return new WeightChangeCommand(oldWeight, newWeight, edge, graphSelection);
	}
	
	/**
	 * Returns new ConvertToWeightedCommand.
	 * @param controller 
	 * 
	 * @return new ConvertToWeightedCommand
	 */
	public Command getConvertToWeightedCommand(PresentationController controller) {
		return new ConvertToWeightedCommand(graphPresentation, controller);
	}
	
	/**
	 * Returns new ConvertToUnweightedCommand.
	 * @param controller
	 * @return new ConvertToUnweightedCommand
	 */
	public Command getConvertToUnweightedCommand(PresentationController controller) {
		return new ConvertToUnweightedCommand(graphPresentation, controller);
	}
	
	/**
	 * Returns new ConvertToUndirectedCommand.
	 * @param controller
	 * @return new ConvertToUndirectedCommand
	 */
	public Command getConvertToUndirectedCommand(PresentationController controller) {
		return new ConvertToUndirectedCommand(graphPresentation, controller);
	}
}
